/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.formserver.voextendinfo.server.core.rpcserviceimp;

import com.inspur.edp.cdp.common.utils.json.JsonUtil;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.viewmodel.exception.VoModelErrorCodes;
import com.inspur.edp.formserver.viewmodel.extendinfo.entity.GspVoExtendInfo;
import com.inspur.edp.formserver.viewmodel.extendinfo.entity.GspVoExtendInfoEntity;
import com.inspur.edp.formserver.viewmodel.extendinfo.entity.VoConfigCollectionInfo;
import com.inspur.edp.formserver.vmmanager.extendinfo.cache.GspVoExtendInfoCacheManager;
import com.inspur.edp.formserver.vmmanager.extendinfo.repository.GspVoExtendInfoRepository;
import com.inspur.edp.formserver.voextendinfo.server.api.GspVoExtendInfoRpcService;

import java.util.ArrayList;
import java.util.List;

public class GspVoExtendInfoRpcServiceImp implements GspVoExtendInfoRpcService {
    private final GspVoExtendInfoRepository voExtendInfoRepository;
    private final GspVoExtendInfoCacheManager gspVoExtendInfoCacheManager;

    public GspVoExtendInfoRpcServiceImp(GspVoExtendInfoRepository voExtendInfoRepository,
                                        GspVoExtendInfoCacheManager gspVoExtendInfoCacheManager) {
        this.voExtendInfoRepository = voExtendInfoRepository;
        this.gspVoExtendInfoCacheManager = gspVoExtendInfoCacheManager;
        //重启应用时清空旧版缓存，防止数据库已更新但缓存未更新的情况
        this.gspVoExtendInfoCacheManager.clear();
    }

    @Override
    public GspVoExtendInfo getVoExtendInfo(String id) {
        if (id == null || id.length() == 0) {
            return null;
        }
        GspVoExtendInfo voExtendInfoFromCache = this.gspVoExtendInfoCacheManager.get(id);
        if (voExtendInfoFromCache != null) {
            return voExtendInfoFromCache;
        }
        GspVoExtendInfoEntity voExtendInfoEntityFromRepo = voExtendInfoRepository.findById(id).orElse(null);
        if (voExtendInfoEntityFromRepo == null)
            return null;
        GspVoExtendInfo voExtendInfoFromRepo = getGspVoExtendInfo(voExtendInfoEntityFromRepo);
        gspVoExtendInfoCacheManager.put(id, voExtendInfoFromRepo);
        return voExtendInfoFromRepo;
    }

    @Override
    public GspVoExtendInfo getVoExtendInfoByConfigId(String configId) {
        if (configId == null || configId.length() == 0) {
            return null;
        }
        GspVoExtendInfo voExtendInfoFromCache = this.gspVoExtendInfoCacheManager.get(configId);
        if (voExtendInfoFromCache != null) {
            return voExtendInfoFromCache;
        }
        List<GspVoExtendInfoEntity> infos = voExtendInfoRepository.getVoExtendInfosByConfigId(configId);
        if (infos.size() > 1) {
            StringBuilder exceptionInfo = new StringBuilder();
            for (GspVoExtendInfoEntity info : infos) {
                exceptionInfo.append(info.getId()).append("\n");
            }
            throw new ViewModelException(VoModelErrorCodes.GSP_VIEWOBJECT_EXTENDINFO_1001, null, configId, exceptionInfo.toString());
        } else if (infos.size() == 0) {
            return null;
        } else {
            GspVoExtendInfo voExtendInfoFromRepo = getGspVoExtendInfo(infos.get(0));
            gspVoExtendInfoCacheManager.put(configId, voExtendInfoFromRepo);
            return voExtendInfoFromRepo;
        }
    }

    @Override
    public List<GspVoExtendInfo> getVoExtendInfos() {
        List<GspVoExtendInfo> gspVoExtendInfos = new ArrayList<>();
        List<GspVoExtendInfoEntity> gspVoExtendInfoEntities = voExtendInfoRepository.findAll();
        if (gspVoExtendInfoEntities == null || gspVoExtendInfoEntities.size() == 0)
            return gspVoExtendInfos;
        for (GspVoExtendInfoEntity entity : gspVoExtendInfoEntities) {
            GspVoExtendInfo gspVoExtendInfo = getGspVoExtendInfo(entity);
            gspVoExtendInfos.add(gspVoExtendInfo);
        }
        return gspVoExtendInfos;
    }

    @Override
    public List<GspVoExtendInfo> getVoId(String beId) {
        List<GspVoExtendInfo> gspVoExtendInfos = new ArrayList<>();
        List<GspVoExtendInfoEntity> gspVoExtendInfoEntities = voExtendInfoRepository.getVoExtendInfoByBeSourceId(beId);
        if (gspVoExtendInfoEntities == null || gspVoExtendInfoEntities.size() == 0)
            return gspVoExtendInfos;
        for (GspVoExtendInfoEntity entity : gspVoExtendInfoEntities) {
            GspVoExtendInfo gspVoExtendInfo = getGspVoExtendInfo(entity);
            gspVoExtendInfos.add(gspVoExtendInfo);
        }
        return gspVoExtendInfos;
    }


    public void saveGspVoExtendInfos(List<GspVoExtendInfo> infos) {
        if (infos == null || infos.size() == 0)
            return;
        List<GspVoExtendInfoEntity> gspVoExtendInfoEntities = new ArrayList<>();
        for (GspVoExtendInfo info : infos) {
            if (info == null)
                continue;
            GspVoExtendInfoEntity entity = getGspVoExtendInfoEntity(info);
            gspVoExtendInfoEntities.add(entity);
        }
        voExtendInfoRepository.saveAll(gspVoExtendInfoEntities);
    }

    @Override
    public void deleteVoExtendInfo(String id) {
        GspVoExtendInfoEntity voExtendInfo = voExtendInfoRepository.findById(id).orElse(null);
        if (voExtendInfo != null) {
            voExtendInfoRepository.deleteById(id);
            gspVoExtendInfoCacheManager.delete(id);
        }
        if (voExtendInfo != null && voExtendInfo.getConfigId() != null) {
            gspVoExtendInfoCacheManager.delete(voExtendInfo.getConfigId());
        }
    }

    private GspVoExtendInfo getGspVoExtendInfo(GspVoExtendInfoEntity gspVoExtendInfoEntity) {
        if (gspVoExtendInfoEntity == null)
            return null;
        GspVoExtendInfo gspVoExtendInfo = new GspVoExtendInfo();
        gspVoExtendInfo.setId(gspVoExtendInfoEntity.getId());
        gspVoExtendInfo.setBeSourceId(gspVoExtendInfoEntity.getBeSourceId());
        gspVoExtendInfo.setConfigId(gspVoExtendInfoEntity.getConfigId());
        gspVoExtendInfo.setCreatedBy(gspVoExtendInfoEntity.getCreatedBy());
        gspVoExtendInfo.setCreatedOn(gspVoExtendInfoEntity.getCreatedOn());
        gspVoExtendInfo.setLastChangedBy(gspVoExtendInfoEntity.getLastChangedBy());
        gspVoExtendInfo.setLastChangedOn(gspVoExtendInfoEntity.getLastChangedOn());
        gspVoExtendInfo.setExtendInfo(gspVoExtendInfoEntity.getExtendInfo());
        gspVoExtendInfo.setVoConfigCollectionInfo(convertToVoConfigCollectionInfo(gspVoExtendInfoEntity.getVoConfigCollectionInfo()));
        return gspVoExtendInfo;
    }

    private GspVoExtendInfoEntity getGspVoExtendInfoEntity(GspVoExtendInfo gspVoExtendInfo) {
        if (gspVoExtendInfo == null)
            return null;
        GspVoExtendInfoEntity gspVoExtendInfoEntity = new GspVoExtendInfoEntity();
        gspVoExtendInfoEntity.setId(gspVoExtendInfo.getId());
        gspVoExtendInfoEntity.setBeSourceId(gspVoExtendInfo.getBeSourceId());
        gspVoExtendInfoEntity.setConfigId(gspVoExtendInfo.getConfigId());
        gspVoExtendInfoEntity.setCreatedBy(gspVoExtendInfo.getCreatedBy());
        gspVoExtendInfoEntity.setCreatedOn(gspVoExtendInfo.getCreatedOn());
        gspVoExtendInfoEntity.setLastChangedBy(gspVoExtendInfo.getLastChangedBy());
        gspVoExtendInfoEntity.setLastChangedOn(gspVoExtendInfo.getLastChangedOn());
        gspVoExtendInfoEntity.setExtendInfo(gspVoExtendInfo.getExtendInfo());
        gspVoExtendInfoEntity.setVoConfigCollectionInfo(JsonUtil.toJson(gspVoExtendInfo.getVoConfigCollectionInfo()));
        return gspVoExtendInfoEntity;
    }

    private VoConfigCollectionInfo convertToVoConfigCollectionInfo(String dbData) {
        if (dbData == null || dbData.isEmpty()) {
            return new VoConfigCollectionInfo();
        }
        VoConfigCollectionInfo configCollectionInfo;
        try {
            configCollectionInfo = JsonUtil.toObject(dbData, VoConfigCollectionInfo.class);
        } catch (JsonUtil.JsonParseException e) {
            throw new ViewModelException(VoModelErrorCodes.GSP_VIEWOBJECT_EXTENDINFO_1002, e, dbData);
        }
        return configCollectionInfo;
    }
}
